/*
 * File:   taskI2CBus.h
 * Author: bram
 *
 * Created on September 29, 2012, 10:52 PM
 */

#ifndef TASKI2C_H
#define	TASKI2C_H


#include <p32xxxx.h>

#include "FreeRTOS.h"
#include "queue.h"
#include "task.h"
#include "semphr.h"

#define I2C_CLK_SET_OUT(bus)	(TRISACLR = bus == 0 ? (1 << 14) : (1 << 2)) //    PORTSetPinsDigitalOut(IOPORT_A,bus == 0 ? BIT_14 : BIT_2))
#define I2C_DAT_SET_OUT(bus)	(TRISACLR = bus == 0 ? (1 << 15) : (1 << 3)) //    PORTSetPinsDigitalOut(IOPORT_A,bus == 0 ? BIT_15 : BIT_3))
#define I2C_CLK_SET(bus)		(PORTASET = bus == 0 ? (1 << 14) : (1 << 2)) //PORTSetBits(IOPORT_A,bus == 0 ? BIT_14 : BIT_2))
#define I2C_DAT_SET(bus)		(PORTASET = bus == 0 ? (1 << 15) : (1 << 3)) //PORTSetBits(IOPORT_A,bus == 0 ? BIT_15 : BIT_3))
#define I2C_CLK_CLR(bus)		(PORTACLR = bus == 0 ? (1 << 14) : (1 << 2)) //PORTClearBits(IOPORT_A,bus == 0 ? BIT_14 : BIT_2))
#define I2C_DAT_CLR(bus)		(PORTACLR = bus == 0 ? (1 << 15) : (1 << 3)) //PORTClearBits(IOPORT_A,bus == 0 ? BIT_15 : BIT_3))

//#define I2C_MIE(bus, value)	(INTEnable(INT_SOURCE_I2C_MASTER(bus), value ? INT_ENABLED : INT_DISABLED));
//#define I2C_BIE(bus, value)	(INTEnable(INT_SOURCE_I2C_ERROR(bus), value ? INT_ENABLED : INT_DISABLED));

enum I2CStates
{
    I2CS_NONE = 0x00,
	I2CS_START = 0x01,
    I2CS_RESTART = 0x02,
    I2CS_WRITE_ADDRESS_ACK = 0x83,
    I2CS_READ_ADDRESS_ACK = 0x84,
	I2CS_READ = 0x05,
    I2CS_READ_ACK = 0x06,
	I2CS_WRITE = 0x87,
	I2CS_STOPPED = 0x08,
	I2CS_DONE = 0x09
};

enum I2CActionState
{
    I2C_STATE_QUEUED = 0,
    I2C_STATE_BUSY,
    I2C_STATE_DONE,
    I2C_STATE_ERROR,
    I2C_STATE_QUEUEERROR
};

struct i2cAction_t
{
    unsigned char address;
    unsigned char * writePacket;
    unsigned char writeLength;
    unsigned char * readPacket;
    unsigned char readLength;

    volatile enum I2CActionState state;

    void (*callbackFunction)(portBASE_TYPE* const);
};

void i2cQueueAction(struct i2cAction_t * action);
void i2cQueueActionFromISR(struct i2cAction_t * action);
void i2cInit();

#endif	/* TASKI2CBUS_H */

